package com.xjrsoft.module.demo.controller;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.Hutool;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.unfbx.chatgpt.ChatGPTClient;
import com.unfbx.chatgpt.OpenAiClient;
import com.unfbx.chatgpt.entity.chat.ChatCompletion;
import com.unfbx.chatgpt.entity.chat.ChatCompletionResponse;
import com.unfbx.chatgpt.entity.chat.Message;
import com.unfbx.chatgpt.entity.completions.CompletionResponse;
import com.xjrsoft.common.annotation.Limit;
import com.xjrsoft.common.constant.GlobalConstant;
import com.xjrsoft.common.model.result.R;
import com.xjrsoft.common.page.ConventPage;
import com.xjrsoft.common.page.PageOutput;
import com.xjrsoft.common.utils.RedisUtil;
import com.xjrsoft.common.utils.VoToColumnUtil;
import com.xjrsoft.config.ChatGptConfig;
import com.xjrsoft.module.demo.dto.AddDemoDto;
import com.xjrsoft.module.demo.dto.DemoListDto;
import com.xjrsoft.module.demo.dto.DemoPageDto;
import com.xjrsoft.module.demo.dto.UpdateDemoDto;
import com.xjrsoft.module.demo.entity.Demo;
import com.xjrsoft.module.demo.service.IDemoService;
import com.xjrsoft.module.demo.vo.DemoPageVo;
import com.xjrsoft.module.demo.vo.DemoVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @title: DemoController
 * @Author tzx
 * @Date: 2022/4/16 23:25
 * @Version 1.0
 */
@RestController
@RequestMapping(GlobalConstant.SYSTEM_MODULE_PREFIX + "/demo")
@Api(value = GlobalConstant.SYSTEM_MODULE_PREFIX + "/demo", tags = "代码生产案例代码")
@AllArgsConstructor
public class DemoController {

    private final IDemoService demoService;

    private final RedisUtil redisUtil;

    private final ChatGptConfig chatGptConfig;

    @GetMapping("/test-chatgpt")
    public R test(@RequestParam String text) {
        //代理可以为null
        Proxy proxy = null;
        //如果使用代理
        if (chatGptConfig.getProxyType() > -1) {
            proxy = new Proxy(chatGptConfig.getProxyType() == 0 ? Proxy.Type.HTTP : Proxy.Type.SOCKS, new InetSocketAddress(chatGptConfig.getProxy(), chatGptConfig.getPort()));
        }

        OpenAiClient openAiClient = OpenAiClient.builder()
                .apiKey(chatGptConfig.getApiKey())
                .proxy(proxy)
                .build();

        //记录上下文
        List<String> msgList = redisUtil.get(GlobalConstant.CHATGPT_PREFIX + StpUtil.getLoginIdAsString(), new TypeReference<List<String>>() {
        });

        if (msgList == null) {
            msgList = new ArrayList<>();
        }
        //将当前的上下文记录下来
        msgList.add(text);

        //默认十分钟过期 十分钟内一直操作 一直更新  如果10分钟没有操作就会过期
        redisUtil.set(GlobalConstant.CHATGPT_PREFIX + StpUtil.getLoginIdAsString(), msgList, 10 * 60);

        List<Message> messages = new ArrayList<>();
        for (String msg : msgList) {
            Message message = Message.builder().role(Message.Role.USER).content(msg).build();
            messages.add(message);
        }


        //简单模型
        //CompletionResponse completions = //openAiClient.completions("我想申请转专业，从计算机专业转到会计学专业，帮我完成一份两百字左右的申请书");
        //最新GPT-3.5-Turbo模型
//        Message message = Message.builder().role(Message.Role.USER).content(text).build();
        ChatCompletion chatCompletion = ChatCompletion.builder().messages(messages).build();
        ChatCompletionResponse chatCompletionResponse = openAiClient.chatCompletion(chatCompletion);
        chatCompletionResponse.getChoices().forEach(e -> {
            System.out.println(e.getMessage());
        });
        //生成一个基本的ERP系统客户表结构的JSON格式示例
        return R.ok(chatCompletionResponse.getChoices().get(0).getMessage().getContent());
    }

    @GetMapping(value = "/list")
    @ApiOperation(value = "demo列表(不分页)")
    public R list(@Valid DemoListDto dto) {
        LambdaQueryWrapper<Demo> queryWrapper = new LambdaQueryWrapper<>();

        List<Demo> list = demoService.list(Wrappers.lambdaQuery(Demo.class)
                .like(StrUtil.isNotBlank(dto.getFieldString()), Demo::getFieldString, dto.getFieldString())
                .eq(ObjectUtil.isNotNull(dto.getFieldInt()), Demo::getFieldInt, dto.getFieldInt())
                .eq(ObjectUtil.isNotNull(dto.getFieldLong()), Demo::getFieldLong, dto.getFieldLong())
                .eq(ObjectUtil.isNotNull(dto.getFieldDouble()), Demo::getFieldDouble, dto.getFieldDouble())
                .between(ObjectUtil.isNotNull(dto.getFieldDatetimeStart()) && ObjectUtil.isNotNull(dto.getFieldDatetimeEnd()), Demo::getFieldDatetime, dto.getFieldDatetimeStart(), dto.getFieldDatetimeEnd())
                .last(GlobalConstant.ORDER_BY + StringPool.SPACE + dto.getField() + StringPool.SPACE + ConventPage.getOrder(dto.getOrder()))
                .select(Demo.class, x -> VoToColumnUtil.fieldsToColumns(DemoPageVo.class).contains(x.getProperty())));

        List<DemoPageVo> demoListVos = BeanUtil.copyToList(list, DemoPageVo.class);
        return R.ok(demoListVos);
    }

    @GetMapping(value = "/page")
    @ApiOperation(value = "demo列表(分页)")
    public R page(@Valid DemoPageDto dto) {

        LambdaQueryWrapper<Demo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StrUtil.isNotBlank(dto.getFieldString()), Demo::getFieldString, dto.getFieldString())
                .eq(ObjectUtil.isNotNull(dto.getFieldInt()), Demo::getFieldInt, dto.getFieldInt())
                .eq(ObjectUtil.isNotNull(dto.getFieldLong()), Demo::getFieldLong, dto.getFieldLong())
                .eq(ObjectUtil.isNotNull(dto.getFieldDouble()), Demo::getFieldDouble, dto.getFieldDouble())
                .between(ObjectUtil.isNotNull(dto.getFieldDatetimeStart()) && ObjectUtil.isNotNull(dto.getFieldDatetimeEnd()), Demo::getFieldDatetime, dto.getFieldDatetimeStart(), dto.getFieldDatetimeEnd())
                .select(Demo.class, x -> VoToColumnUtil.fieldsToColumns(DemoPageVo.class).contains(x.getProperty()));
        IPage<Demo> page = demoService.page(ConventPage.getPage(dto), queryWrapper);
        PageOutput<DemoPageVo> pageOutput = ConventPage.getPageOutput(page, DemoPageVo.class);
        return R.ok(pageOutput);
    }

    @GetMapping(value = "/info")
    @ApiOperation(value = "根据id查询demo信息")
    public R info(@RequestParam Long id) {
        Demo demo = demoService.getById(id);
        if (demo == null) {
            return R.error("找不到此数据！");
        }
        return R.ok(BeanUtil.toBean(demo, DemoVo.class));
    }

    @PostMapping
    @ApiOperation(value = "新增demo")
    public R add(@Valid @RequestBody AddDemoDto dto) {
        Demo demo = BeanUtil.toBean(dto, Demo.class);
        return R.ok(demoService.save(demo));
    }

    @PutMapping
    @ApiOperation(value = "修改demo")
    public R update(@Valid @RequestBody UpdateDemoDto dto) {

        Demo demo = BeanUtil.toBean(dto, Demo.class);

        return R.ok(demoService.updateById(demo));
    }

    @DeleteMapping
    @ApiOperation(value = "删除")
    public R delete(@Valid @RequestBody List<Long> ids) {
        return R.ok(demoService.removeBatchByIds(ids));
    }


    @GetMapping(value = "/test")
    @ApiOperation(value = "cccccc")
    @Limit(key = "cachingTest", count = 5, time = 2, msg = "当前排队人数较多，请稍后再试！")
    public R test() throws InterruptedException {
        System.out.println("xxxxxxxxxxxxxxxxx");
        return R.ok();
    }
}
